package org.xqh.study.certs;

import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;

import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Date;

public class GenerateCertTest {
    public static void main(String[] args) throws Exception {
        // Add Bouncy Castle as a security provider
        java.security.Security.addProvider(new BouncyCastleProvider());

        // Generate key pair
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
        keyPairGenerator.initialize(2048, new SecureRandom());
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        // Generate self-signed certificate
        X509Certificate cert = generateSelfSignedCertificate(keyPair);

        // Print the certificate
        System.out.println(cert);
    }

    public static X509Certificate generateSelfSignedCertificate(KeyPair keyPair) throws Exception {
        long now = System.currentTimeMillis();
        Date startDate = new Date(now);

        // Set the certificate validity period
        Date endDate = new Date(now + 365 * 24 * 60 * 60 * 1000L); // 1 year

        // Certificate serial number
        BigInteger serialNumber = new BigInteger(Long.toString(now));

        // Issuer and subject details
        String issuer = "CN=Test CA, OU=Test, O=Test, L=Test, ST=Test, C=Test";
        String subject = "CN=Test, OU=Test, O=Test, L=Test, ST=Test, C=Test";

        // Content signer
        ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(keyPair.getPrivate());

        // Create the certificate
        JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(
                new org.bouncycastle.asn1.x500.X500Name(issuer),
                serialNumber,
                startDate,
                endDate,
                new org.bouncycastle.asn1.x500.X500Name(subject),
                keyPair.getPublic());

        // Build the certificate
        X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC")
                .getCertificate(certBuilder.build(contentSigner));

        return cert;
    }
}
